package model

import (
	"fmt"
	"os"
	"time"
	"encoding/json"
)

type PutOrder struct {
	OrderType int
	CustomerId int
	CustomerName string
	NextSinglePersonId int
	NextSinglePersonName string
	Meal string
	MealList []*Meal `form:"-"`
	TotalPrice int64
	Region string
}

type Order struct {
	OrderId int `xorm:"pk autoincr"`
	OrderType int
	OrderState int
	CustomerId int
	CustomerName string
	NextSinglePersonId int
	NextSinglePersonName string
	Meal string
	MealList []*Meal `xorm:"-"`
	TotalPrice int64
	Region string
	CreatedAt time.Time
  	UpdatedAt time.Time
}

func (o *Order)InsertOrder(ov *PutOrder) map[string]string{
	var od *Order
	od.OrderType = ov.OrderType
	od.OrderState = 1
	od.CustomerId = ov.CustomerId
	od.CustomerName  = ov.CustomerName
	od.NextSinglePersonId = ov.NextSinglePersonId
	od.NextSinglePersonName  = ov.NextSinglePersonName
	od.Meal = ov.Meal
	od.TotalPrice = ov.TotalPrice
	od.Region = ov.Region
	od.CreatedAt = time.Now()
	od.UpdatedAt = time.Now()

	_, err := x.Insert(od)
	if err != nil{
		return map[string]string{"message": "失败","code":"400"}
	}
	return map[string]string{"message": "成功","code":"200"}
}

func (o *Order)QuerytOrder(ot int, cId int) *Order{
	var ov *Order
	x.Where("order_type = ?", ot).And("customer_id = ?", cId).Desc("created_at").Limit(1,0).Get(ov)
	return ov
}

func (o *Order)QuerytDateOrder(td int, cId int) []*Order{
	var ov []*Order
	x.Where("customer_id = ?", cId).And("created_at >= ?", time.Now().AddDate(0,0,-td).Format("2006-01-02 15:04:05")).
		Desc("created_at").Limit(1).Find(ov)
	return ov
}

func (o *Order)QuerytOrderList(otId int, cId int) []*Order{
	var ovList []*Order
	x.Where("order_type = ?", otId).And("customer_id = ?", cId).And("created_at >= ?", time.Now().AddDate(0,-1,0).Format("2006-01-02 15:04:05")).Find(&ovList)
	return ovList
}

func (o *Order)QuerytOrderYearList(otId int, cId int) []*Order{
	var ovList []*Order
	x.Where("order_type = ?", otId).And("customer_id = ?", cId).And("created_at >= ?", time.Now().AddDate(-1,0,0).Format("2006-01-02 15:04:05")).Find(&ovList)
	return ovList
}

func GetCount(year int, month int) (days int) {
	if month != 2 {
		if month == 4 || month == 6 || month == 9 || month == 11 {
			days = 30

		} else {
			days = 31
			fmt.Fprintln(os.Stdout, "The month has 31 days");
		}
	} else {
		if (((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0) {
			days = 29
		} else {
			days = 28
		}
	}
	return
}

func GetMonth(m string) int{
	switch m {
	case "January":
		return 1
	case "February":
		return 2
	case "March":
		return 3
	case "April":
		return 4
	case "May":
		return 5
	case "June":
		return 6
	case "July":
		return 7
	case "August":
		return 8
	case "September":
		return 9
	case "October":
		return 10
	case "November":
		return 11
	case "December":
		return 12
	}
	return 0
}

func (o *Order)InsertOrderRule(ov *PutOrder) map[string]string{
	var a *Account
	var c *Customer
	var r *Rule
	var rct *RuleCustomersType
	var rd *RuleDepartment
	var so *SingleOrder
	var m *Meal
	var mo *MonthlyOrder
	var ao *AccumulativeOrder
	var ppr *ProductPurchaseRestrictions

	var sumProduct int64 = 0
	for _, mv := range ov.MealList {
		p, err := ppr.QueryProduct(mv.MealId)
		if err != nil {
			return map[string]string{"message": "查询产品报错", "code": "500"}
		}
		if p.Id != 0 {
			sumProduct += mv.Number
			if p.RestrictionType == 1 {
				for _, opv := range o.QuerytDateOrder(p.IntervalLimit, ov.CustomerId) {
					if err := json.Unmarshal([]byte(opv.Meal), &opv.MealList); err == nil {
						for _, op := range opv.MealList {
							if op.MealId == p.ProductId {
								sumProduct += op.Number
							}
						}
					}
				}
			} else if p.RestrictionType == 2 {
				thistMonth := time.Now()
				count := GetCount(thistMonth.Year(), GetMonth(thistMonth.Month().String()))
				for _, opdv := range o.QuerytDateOrder(count, ov.CustomerId) {
					if err := json.Unmarshal([]byte(opdv.Meal), &opdv.MealList); err == nil {
						for _, opd := range opdv.MealList {
							if opd.MealId == p.ProductId {
								sumProduct += opd.Number
							}
						}
					}
				}
			}
			if int(sumProduct) > p.SumLimit {
				return map[string]string{"message": "超过限制数", "code": "400"}
			}
		}
	}

	rcList := r.QueryRuleByOrderType(ov.OrderType)
	if rcList == nil{
		return o.InsertOrder(ov)
	}else{
		for _, v := range rcList{
			rdv := rd.QueryRuleDepartment(a.QueryAccountOne(ov.NextSinglePersonId).DepartMentId,v.RuleId)
			if rdv != nil && rdv.RuleDepartmentId != 0{
				rctv := rct.QueryRuleCustomersTypeByCustomersType(c.QueryCustomerById(ov.CustomerId).CustomerType, v.RuleId)
				if rctv != nil && rctv.RuleCustomersTypeId != 0{
					if rctv.OrderInterval >= int(time.Now().Sub(o.QuerytOrder(ov.OrderType, ov.CustomerId).CreatedAt).Hours()/24){
						return map[string]string{"message": "此客户的该类型订单间隔小于"+string(rctv.OrderInterval)+"天","code":"400"}
					}
				}

				sov := so.QuerySingleOrder(rctv.RuleCustomersTypeId)
				if sov != nil && sov.SingleOrderId != 0{
					mvList := m.QueryMealList(sov.SingleOrderId)
					if mvList != nil {
						for _, mv := range ov.MealList{
							for _, rmv := range mvList{
								if mv.MealId == rmv.MealId{
									ov.TotalPrice = ov.TotalPrice - rmv.Price
								}
							}
						}
						if ov.TotalPrice >= sov.AmountMoney{
							return map[string]string{"message": "此类型订单单笔不能超过"+string(sov.AmountMoney)+"元","code":"400"}
						}
					}
				}

				mov := mo.QueryMonthlyOrder(rctv.RuleCustomersTypeId)
				if mov != nil && mov.MonthlyOrderId != 0{
					nvList := m.QueryMealListMonth(mov.MonthlyOrderId)
					if nvList != nil{
						var monTemPrice int64
						var thisOrderPrice int64
						for _, ovl := range o.QuerytOrderList(ov.OrderType, ov.CustomerId){
							if err := json.Unmarshal([]byte(ovl.Meal), &ovl.MealList); err == nil{
								for _, n := range nvList{
									for _, e := range ovl.MealList{
										if e.MealId == n.MealId{
											monTemPrice = monTemPrice + ovl.TotalPrice - e.Price*e.Number
										}
									}

									for _, i := range ov.MealList{
										if i.MealId == n.MealId{
											thisOrderPrice = thisOrderPrice - i.Price*i.Number
										}
									}
								}
							}else{
								return map[string]string{"message": "解析订单套餐失败","code":"400"}
							}
						}
						if monTemPrice + thisOrderPrice > mov.AmountMoney{
							return map[string]string{"message": "此类订单每月累计不能超过"+string(mov.AmountMoney)+"元","code":"400"}
						}
					}
				}

				aov := ao.QueryAccumulativeOrder(rctv.RuleCustomersTypeId)
				if aov != nil && aov.AccumulativeOrderId != 0{
					yvList := m.QueryMealListYear(aov.AccumulativeOrderId)
					if yvList != nil {
						var yearTemPrice int64
						var thisOrderPrice int64
						for _, aol := range o.QuerytOrderYearList(ov.OrderType, ov.CustomerId){
							if err := json.Unmarshal([]byte(aol.Meal), &aol.MealList); err == nil{
								for _, y := range yvList{
									for _, a := range aol.MealList{
										if a.MealId == y.MealId{
											yearTemPrice = yearTemPrice + aol.TotalPrice - a.Price*a.Number
										}
									}

									for _, h := range ov.MealList{
										if h.MealId == y.MealId{
											thisOrderPrice = thisOrderPrice - h.Price*h.Number
										}
									}
								}
							}else{
								return map[string]string{"message": "解析订单套餐失败","code":"400"}
							}
						}
						if yearTemPrice + thisOrderPrice > aov.AmountMoney{
							return map[string]string{"message": "此类订单每年累计不能超过"+string(aov.AmountMoney)+"元","code":"400"}
						}
					}
				}
			}
		}

		return o.InsertOrder(ov)
	}
}

